Thread: [SOCKETS] Solaris server in C, NT client in VB

  1. #1
    Registered User
    Join Date
    May 2002
    Posts
    2

    [SOCKETS] Solaris server in C, NT client in VB

    Warning! C/sockets newbie ahead!

    I seem to be having some issues here trying to get these 2 apps to communicate. I'm getting a weird behavior issue but I don't know if it's server side or client side. The client is a simple VB app with a few buttons to connect, send, and disconnect. It sends test in one textbox and receives it in another. That works fine. The problem is that after the winsock.sendata method is called on the client, the tcpClient.state becomes 8 ("Peer is closing the connection"). I'm not sure why this happens. I thought it might be the close( new_fd ) line in the server code but it happens even with that line commented out. The server code is modified Beej code (Thanks Beej!). I took out the fork just to make it a little easier for me to follow what is happening. The problem happens in both versions though. Here is the server code, the client code is all of about 10 lines and not really worth posting on a C board. Yes, I know I should just use a C client but I don't have a compiler I can use at the moment.

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <sys/wait.h>
    #include <signal.h>

    #define MYPORT 60000 // the port users will be connecting to

    #define BACKLOG 10 // how many pending connections queue will hold

    #define MAXDATASIZE 100 // max number of bytes we can get at once

    void sigchld_handler( int s )
    {
    while( wait( NULL ) > 0 );
    }

    int main( void )
    {
    /* BEGIN FUNCTION PROTOTYPES */
    void checksystem( );
    /* END FUNCTION PROTOTYPES */

    int numbytes, fd[ 2 ];
    char buf[ MAXDATASIZE ];

    int sockfd, new_fd; // listen on sock_fd, new connection on new_fd
    struct sockaddr_in my_addr; // my address information
    struct sockaddr_in their_addr; // connector's address information
    int sin_size;
    struct sigaction sa;
    int yes = 1;

    if( ( sockfd = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 )
    {
    perror( "socket" );
    exit( 1 );
    }

    if( setsockopt( sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof( int ) ) == -1 )
    {
    perror( "setsockopt" );
    exit( 1 );
    }

    my_addr.sin_family = AF_INET; // host byte order
    my_addr.sin_port = htons( MYPORT ); // short, network byte order
    my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
    memset( &( my_addr.sin_zero ), '\0', 8 ); // zero the rest of the struct

    if( bind( sockfd, ( struct sockaddr * )&my_addr, sizeof( struct sockaddr ) ) == -1 )
    {
    perror( "bind" );
    exit( 1 );
    }

    if( listen( sockfd, BACKLOG ) == -1 )
    {
    perror( "listen" );
    exit( 1 );
    }

    sa.sa_handler = sigchld_handler; // reap all dead processes
    sigemptyset( &sa.sa_mask );
    sa.sa_flags = SA_RESTART;
    if( sigaction( SIGCHLD, &sa, NULL ) == -1 )
    {
    perror( "sigaction" );
    exit( 1 );
    }

    while( 1 )
    { // main accept() loop
    sin_size = sizeof( struct sockaddr_in );
    if( ( new_fd = accept( sockfd, ( struct sockaddr * )&their_addr, &sin_size ) ) == -1 )
    {
    perror( "accept" );
    continue;
    }

    printf( "server: got connection from %s\n", inet_ntoa( their_addr.sin_addr ) );
    printf( "server: new_fd = %d\n", new_fd );

    if( ( numbytes = recv( new_fd, buf, MAXDATASIZE-1, 0 ) ) == -1 ) {
    perror( "recv" );
    exit( 1 );
    }
    buf[ numbytes ] = '\0';
    if( strcmp( buf, "testmatch" ) == 0 )
    {
    if( send( new_fd, "They matched!\n" , 14, 0 ) == -1 )
    perror( "send" );
    /*checksystem( );*/
    }

    if( send( new_fd, buf, 14, 0 ) == -1 )
    perror( "send" );
    close( new_fd );
    }

    return 0;
    }

    void checksystem( )
    {
    //forked process....
    }
    Last edited by Daveg27; 05-23-2002 at 08:26 AM.

  2. #2
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    First off, please use code tags in future when posting code.

    Now, I compiled and ran your code, and it did basically appear to work. The only comments I have are:

    >if (strcmp(buf, "testmatch") == 0)
    This will never be true if the buf variable ends with a newline character(s). You'll need to check to see if the client is sending them or not. Maybe that's your problem?

    For debugging purposes add the following :
    >printf ("Received %d bytes, %s\n", numbytes, buf);

    Yes, the close() will cause the client to see a peer closing connection message. But I did get your message out on the server:
    Code:
    $ ./a
    server: got connection from 127.0.0.1
    server: new_fd = 4
    Received 1 bytes, t
    And I did get a message back to the client (for which I used the standard Windows telnet client).

    If you want, you can pause the server just before the close() call to see if the client gets disconnected (mine didn't).
    Code:
    ......
    printf ("Paused\n");
    while (getchar() != '\n');
    printf ("Released\n");
    close(new_fd);
    .....
    If this doesn't help, let us know where your stuck again.....
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  3. #3
    Registered User
    Join Date
    May 2002
    Posts
    2
    First off, please use code tags in future when posting code.
    LOL, I saw your sig in another post immediately after I posted this. Oops, newbie mistake.

    >if (strcmp(buf, "testmatch") == 0)
    This will never be true if the buf variable ends with a newline character(s).
    This little comparison is working with my client. The passed string is coming from a text box in VB, I guess there is not a newline character in there. This is just a little test app for me to learn how sockets work though. As this progresses I will probably switch to sending and comparing ints picked from a menu instead of user typed text. Less chance of mistakes that way.

    I should have been clearer in my original post. The VB client sends and receives text exactly like it should. The problem is the server appears to be closing the connection but never finishes. The client sits in the "Peer is closing the connection" state. I'm starting to think that the problem is at my client (VB winsock) and not the server, like I said this is basically just Beej's server code and it seems to works fine with a UNIX C client.

    BTW, when I add back in the fork() I get another message at the server:
    server: got connection from XXX.XXX.XXX.XXX
    server: new_fd = 6
    accept: Interrupted system call <-- this line here.

    I don't know what is causing that. Is accept() the system call that is being interrupted? What is interrupting it? Could that be related to the client hanging in the closing connection state?

    Thanks for your help, Hammer. I may actually have to go out and get a book for this stuff!

  4. #4
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >Oops, newbie mistake.
    No prob! Now ya know.

    >accept: Interrupted system call <-- this line here.
    accept is being interrupted by the child process sending a signal back to the parent when it terminates (SIGCHLD, if I remember write). You can either ignore SIGCHLD, or you can code accept() to handle the interrupt better (errno is set to EINTR)

    >The client sits in the "Peer is closing the connection" state.
    If you're using fork(), the child process will need to stay in a loop, reading the file descriptor until the client closes the connection. Without checking your latest code, I can't tell what your prog is doing.

    >I may actually have to go out and get a book for this stuff!
    Personally, I found the latest Beej's pdf very good (and free!)
    Get it here
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. server client application - (i really need your help)
    By sarahnetworking in forum C Programming
    Replies: 3
    Last Post: 03-01-2008, 10:54 PM
  2. Socket Programming Problem!!!!
    By bobthebullet990 in forum Networking/Device Communication
    Replies: 2
    Last Post: 02-21-2008, 07:36 PM
  3. Where's the EPIPE signal?
    By marc.andrysco in forum Networking/Device Communication
    Replies: 0
    Last Post: 12-23-2006, 08:04 PM
  4. Unicode vurses Non Unicode client server application with winsock2 query?
    By dp_76 in forum Networking/Device Communication
    Replies: 0
    Last Post: 05-16-2005, 07:26 AM
  5. socket question
    By Unregistered in forum C Programming
    Replies: 3
    Last Post: 07-19-2002, 01:54 PM